import { Destroyable, react, reactJson, Event, track, bind, HasOwner, createNextAnimateFrameEvent } from "xbsj-xe2/dist-node/xe2-base-utils";
import { ObjResettingWithEvent, SceneObject, Viewer } from 'xbsj-xe2/dist-node/xe2-base-objects';
import { formatTime, getUrlParam } from "../utils"
import { MyProjectManager } from "../MyProjectManager";
import { EditorSubmit, getServer, getTasksRunning, listServer, reqCancelTask, reqDeleteRecordList, reqGetOneTileService, reqGetPort, reqGetRecordlist, reqGetSetting } from '@/api';
import { ElMessage } from "element-plus";
import { ES3DTileset } from "esobjs-xe2-plugin/dist-node/esobjs-xe2-plugin-main";
import { id } from "element-plus/es/locale";
import axios from "axios";
import loading from "@/api/loading";
// import { ClippingWrapper } from "./ClippingWrapper";
import { FreeDrawingResettting } from "./freeDrawingResettting";
import { EditPolygon } from "./editPolygon";

export class ModelserManager extends HasOwner<MyProjectManager> {

    // Modelser服务id
    private _modelserId = this.dv(react<string>(""));
    get modelserId() { return this._modelserId.value; }
    get modelserIdChanged() { return this._modelserId.changed; }
    set modelserId(value: string) { this._modelserId.value = value; }

    // 服务路径
    private _modelserUrl = this.dv(react<string>(""));
    get modelserUrl() { return this._modelserUrl.value; }
    get modelserUrlChanged() { return this._modelserUrl.changed; }
    set modelserUrl(value: string) { this._modelserUrl.value = value; }

    // 是不是Modelser服务
    private _isModelserService = this.dv(react<boolean>(false));
    get isModelserService() { return this._isModelserService.value; }
    get isModelserServiceChanged() { return this._isModelserService.changed; }
    set isModelserService(value: boolean) { this._isModelserService.value = value; }

    // 编辑几何体
    private _editPolygon = this.dv(new EditPolygon(this.owner, this));
    get editPolygon() { return this._editPolygon; }

    // ES3DTileset
    private _eS3DTileset = this.dv(this.owner.createSceneObject(ES3DTileset) as ES3DTileset);
    get eS3DTileset() { return this._eS3DTileset; }

    // url切换
    private _urlCutEvent = this.dv(new Event());
    get urlCutEvent() { return this._urlCutEvent; }

    private _timer: any = null
    get timer() { return this._timer; }
    set timer(value: any) { this._timer = value; }

    // 弹出框事件
    private _dialogEvent = this.dv(new Event<[string]>());
    get dialogEvent() { return this._dialogEvent; }

    // 记录列表
    private _recordList = this.dv(react<any>([]));
    get recordList() { return this._recordList.value; }
    get recordListChanged() { return this._recordList.changed; }
    set recordList(value: any) { this._recordList.value = value; }

    // 任务进度
    private _taskProgress = this.dv(react<any>([]));
    get taskProgress() { return this._taskProgress.value; }
    get taskProgressChanged() { return this._taskProgress.changed; }
    set taskProgress(value: any) { this._taskProgress.value = value; }

    // 进度条信息
    private _percentageInfo = this.dv(react<any>({}));
    get percentageInfo() { return this._percentageInfo.value; }
    get percentageInfoChanged() { return this._percentageInfo.changed; }
    set percentageInfo(value: any) { this._percentageInfo.value = value; }

    // 标记点击
    private _isHighlight = this.dv(react<string>(""));
    get isHighlight() { return this._isHighlight.value; }
    set isHighlight(value) { this._isHighlight.value = value }
    get isHighlightChanged() { return this._isHighlight.changed; }

    // 创建事件
    private _createEvent = this.dv(new Event());
    get createEvent() { return this._createEvent; }


    // 获取列表数据
    async getRecordlist() {
        try {
            const param = {
                serverid: this.modelserId,
            }
            const res = await reqGetRecordlist(param);
            // @ts-ignore
            if (res.data.code != "1000") return;
            this.recordList = res.data.data
        } catch (error) {
            console.error(error);
        }
    }

    // 删除列表记录
    async delRecord(id: any) {
        try {
            const param = {
                id: JSON.stringify(id),
                serverid: this.modelserId,
            }
            const res = await reqDeleteRecordList(param)
            // @ts-ignore
            if (res.data.code == "1000") {
                loading.closeLoading()
                ElMessage.success("删除成功");
            } else {
                loading.closeLoading()
                ElMessage.error("删除失败");
            }

        } catch (error) {
            loading.closeLoading()
            console.error(error);
        }
    }

    // 设置服务参数
    setServerParam(json: any, serverParam: any) {

        json.forEach((e: any) => {
            // 不是文件夹
            if (e.sceneObj) {
                const obj = {
                    esobjId: e.sceneObj.id,
                    bottom: e.sceneObj.bottom,
                    ceilling: e.sceneObj.ceilling,
                    absoluteBottom: e.sceneObj.absoluteBottom,
                    absoluteCeilling: e.sceneObj.absoluteCeilling,
                    operation: e.sceneObj.operation,
                    srcGeom: e.sceneObj.srcGeom,
                }
                serverParam.push(obj)
            }
            // 如果没有子节点，则不执行
            if (e.children && e.children.length > 0) {
                this.setServerParam(e.children, serverParam)
            }
        });

    }

    // 提交记录
    async submit() {
        try {
            const sceneTree = this.owner.modelserSceneTreeWrapper?.json.root.children
            const serverParam: any = []

            // 设置服务参数
            this.setServerParam(sceneTree, serverParam)

            const srcJson = JSON.stringify({
                sceneTree,
                serverParam
            })

            const param = {
                "serverid": this.modelserId,
                "srcJson": srcJson,
            }
            const res = await EditorSubmit(param) as any;
            if (res.data.code == "1000") {
                loading.closeLoading()
                ElMessage.success(res.data.msg);

                // 获取记录列表
                this.getRecordlist()
                // 获取任务进度
                this.getTaskProgress()
            } else {
                loading.closeLoading()
                ElMessage.error(res.data.msg);
            }
        } catch (error) {
            loading.closeLoading()
            console.error(error)
        }
    }
    // 获取任务进度
    getTaskProgress() {
        this.timer = setInterval(async () => {
            try {
                const res = await getTasksRunning(this.modelserId);
                if (res.data.code != "1000") return;
                // 创建完成
                if (this.taskProgress.length > res.data.data.length) {
                    // 刷新 modelserUrl
                    this.refresh()
                    // 删除sceneTree上面的节点
                    this.owner.modelserSceneTreeWrapper?.destroyAllSceneObjectTreeItems()
                    this.owner.modelserPropSceneTree = undefined
                    // 清空参数
                    this.clear()
                    if (this.timer) clearInterval(this.timer)
                }
                this.taskProgress = res.data.data
                // }
            } catch (error) {
                console.error(error);
            }
        }, 1000)
    };

    // 取消正在进行的任务
    async cancelTask(id: any) {
        try {
            const res = await reqCancelTask(id);
            // @ts-ignore
            if (res.data.code == "1000") {
                ElMessage.success("任务取消成功");
            } else {
                ElMessage.error("任务取消失败");
            }
        } catch (error) {
            console.error(error);
        }
    }

    // 刷新
    async refresh() {
        try {
            const res = await getServer(this.modelserId);
            if (res.data.code != "1000") return;
            const ip = this.modelserUrl.match(/^(https?:\/\/[^\/]+)/)?.[1]
            let url = ip + "/3dtiles/" + res.data.data.id + "-" + res.data.data.id + "-cache";

            const time = +new Date()
            if (res.data.data.lastVersioning) {
                url += "/" + res.data.data.lastVersioning + `/tileset.json?t=${time}`;
            } else {
                url += `/tileset.json?t=${time}`;
            }
            this.eS3DTileset.url = url
        } catch (error) {
            console.error(error);
        }
    }


    // 验证是不是modelser服务
    async verifyModelserService(url: string) {
        try {
            // 是不是一个服务
            const res2 = await axios({
                url: this.modelserUrl,
                method: "get",
            })
            console.log(res2, res2);

            // 如果是一个服务
            if (res2.data.hasOwnProperty("root")) {
                // 是不是一个modelser服务
                const res = await listServer();

                // @ts-ignore
                if (res.data.code != "1000") return false;

                const cacheBucket = url.split("/").find(e => e.includes("-"))
                const flag = res.data.data.some((item: any) => item.cacheBucket.includes(cacheBucket))
                if (flag) {
                    // 设置modelserv id
                    this.modelserId = res.data.data.find((item: any) => item.cacheBucket.includes(cacheBucket)).id
                    return true
                } else {
                    return false
                }
            } else {
                return false
            }




        } catch (error) {
            console.error(error);
            return false
        }

    }

    // 清除cimrts窗口
    private _clearModelserWindowEvent = this.dv(new Event());
    get clearModelserWindowEvent() { return this._clearModelserWindowEvent; }

    clear() {
        // 是否是Modelser服务
        this.isModelserService = false
        // 清除Modelser窗口
        this.clearModelserWindowEvent.emit()
        // 场景树上的对象删除
        this.owner.modelserSceneTreeWrapper?.destroyAllSceneObjectTreeItems()
        this.owner.modelserPropSceneTree = undefined

    }

    constructor(owner: MyProjectManager) {
        super(owner);
        this.eS3DTileset.allowPicking = true

        {
            const updata = async (url: string) => {
                // 清除参数
                this.clear()
                if (!url) {
                    this.eS3DTileset.url = ""
                    this.urlCutEvent.emit()
                    return;
                }

                // 验证是不是Modelser服务
                const flag = await this.verifyModelserService(url)
                if (flag) {
                    this.isModelserService = true
                    // 设置eSDSTileset url
                    await this.refresh()


                }
                else {
                    if (this.timer) clearInterval(this.timer)
                    this.isModelserService = false
                    ElMessage.error('请输入正确的Modelser服务地址')
                    this.eS3DTileset.url = ""
                }
                this.urlCutEvent.emit()
            }
            this.dispose(this.modelserUrlChanged.don(updata))
        }

        {
            const updata = async () => {
                if (!this.taskProgress.length) {
                    this.percentageInfo = {
                        percentage: 0,
                        id: "",
                        taskId: ""
                    }
                } else {
                    const percentage = Math.floor(this.taskProgress[0].success / this.taskProgress[0].total * 10000) / 100
                    this.percentageInfo = {
                        percentage: this.taskProgress[0].total ? (percentage <= 100 ? percentage : 100) : 0,
                        id: JSON.parse(this.taskProgress[0].task.param).dto.id,
                        taskId: this.taskProgress[0].task.taskId
                    }
                }
                // console.log("this.percentageInfo", this.percentageInfo);

            }

            this.dispose(this.taskProgressChanged.don(updata))
        }

        {
            const obj = getUrlParam();
            this.dispose(this.eS3DTileset.tilesetReady.disposableOnce(() => {
                if (obj.hasOwnProperty("cameraInfo")) return;
                this.eS3DTileset.flyTo()
            }))
        }

    }

}